{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c048ea81",
   "metadata": {},
   "outputs": [],
   "source": [
    "##ols model\n",
    "from sklearn.linear_model import LinearRegression\n",
    "\n",
    "# OLS with all features\n",
    "OLS = LinearRegression().fit(X_trn,y_trn)\n",
    "evaluate(y_trn, OLS.predict(X_trn), insample=True)\n",
    "evaluate(y_tst, OLS.predict(X_tst))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87b49751",
   "metadata": {},
   "outputs": [],
   "source": [
    "##pls model\n",
    "from sklearn.cross_decomposition import PLSRegression\n",
    "\n",
    "params = {'n_components': [1, 5, 10, 50]}\n",
    "PLS = val_fun(PLSRegression,params=params,X_trn=X_trn,y_trn=y_trn,X_vld=X_vld,y_vld=y_vld)\n",
    "\n",
    "pls_pred_is = PLS.predict(X_trn)\n",
    "pls_pred_os = PLS.predict(X_tst)\n",
    "evaluate(y_trn, pls_pred_is, insample=True) \n",
    "evaluate(y_tst, pls_pred_os)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "161d743d",
   "metadata": {},
   "outputs": [],
   "source": [
    "##pcr model\n",
    "from sklearn.linear_model import LinearRegression, HuberRegressor\n",
    "from sklearn.decomposition import PCA\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "class PCRegressor:\n",
    "    \n",
    "    def __init__(self,n_PCs=1,loss='mse'):\n",
    "        self.n_PCs = n_PCs\n",
    "        if loss not in ['huber','mse']:\n",
    "            raise AttributeError(\n",
    "            f\"The loss should be either 'huber' or 'mse', but {loss} is given\"\n",
    "            )\n",
    "        else:\n",
    "            self.loss = loss\n",
    "        \n",
    "    def set_params(self, **params):\n",
    "        for param in params.keys():\n",
    "            setattr(self, param, params[param])\n",
    "        return self\n",
    "        \n",
    "    def fit(self,X,y):\n",
    "        X = np.array(X)\n",
    "        N,K = X.shape\n",
    "        y = np.array(y_trn).reshape((N,1))\n",
    "        self.mu = np.mean(X,axis=0).reshape((1,K))\n",
    "        self.sigma = np.std(X,axis=0).reshape((1,K))\n",
    "        self.sigma = np.where(self.sigma==0,1,self.sigma)\n",
    "        X = (X-self.mu)/self.sigma\n",
    "        pca = PCA()\n",
    "        X = pca.fit_transform(X)[:,:self.n_PCs]\n",
    "        self.pc_coef = pca.components_.T[:,:self.n_PCs]\n",
    "        if self.loss == 'mse':\n",
    "            self.model = LinearRegression().fit(X,y)\n",
    "        else:\n",
    "            self.model = HuberRegressor().fit(X,y)\n",
    "        return self\n",
    "    \n",
    "    def predict(self,X):\n",
    "        X = np.array(X)\n",
    "        X = (X-self.mu)/self.sigma\n",
    "        X = X @ self.pc_coef\n",
    "        return self.model.predict(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "96f62ae9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# principal component regression\n",
    "params = {'n_PCs':[1,3,5,7,10,50],'loss':['mse','huber']}\n",
    "PCR = val_fun(PCRegressor,params=params,X_trn=X_trn,y_trn=y_trn,X_vld=X_vld,y_vld=y_vld,sleep=3)\n",
    "\n",
    "evaluate(y_trn, PCR.predict(X_trn), insample=True) \n",
    "evaluate(y_tst, PCR.predict(X_tst))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "fhuan",
   "language": "python",
   "name": "fhuan"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
